from django.shortcuts import render
from django_redis import get_redis_connection

from rest_framework import status
from rest_framework.decorators import action
from rest_framework.generics import CreateAPIView, GenericAPIView,mixins, RetrieveAPIView, UpdateAPIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import GenericViewSet
from rest_framework_jwt.views import ObtainJSONWebToken

from apps.carts.utils import merge_cookie_redis_cart
from apps.goods.models import SKU
from apps.users.models import User, Address

from apps.users.seralizers import RegisterUserSerializer, UserInfoSerializer, AddressSerializer, \
    UserBrowerHistorySerializer

# 校验用户名是否存在
from celery_tasks.email.tasks import send_email


class CheckUsernameView(APIView):
    def get(self, request, username):
        # 将用户名拿到数据库查询
        count = User.objects.filter(username=username).count()

        # 组织返回数据
        dict_data = {
            "count": count
        }

        return Response(data=dict_data, status=status.HTTP_200_OK)

# 校验手机号是否存在
class CheckMobileView(APIView):
    def get(self, request, mobile):
        # 将手机号拿到数据库查询
        count = User.objects.filter(mobile=mobile).count()

        # 组织返回数据
        dict_data = {
            "count": count
        }

        return Response(data=dict_data, status=status.HTTP_200_OK)

#注册视图
class RegisterUserView(CreateAPIView):

    serializer_class = RegisterUserSerializer

# 用户中心数据获取视图
class UserInfoView(RetrieveAPIView):
    serializer_class = UserInfoSerializer

    # 认证用户，使视图需要登陆才能访问
    permission_classes = [IsAuthenticated]

    # 重写get_object 方法，为了能用3级视图
    def get_object(self):
        return self.request.user

#发送邮件
class EmailSendView(UpdateAPIView):
    #绑定序列化器
    serializer_class = UserInfoSerializer
    #认证用户，需要登陆才行
    permission_classes = [IsAuthenticated]


    def get_object(self):
        return  self.request.user

    #修改邮箱，发送邮件
    def put(self,request):

        #调用父类的put方法，更新用户数据库的邮箱
        super().put(request,partial=True)

        #生成url地址
        verify_url=self.get_object().generate_verify_url()

        #发送邮箱
        send_email.delay(verify_url, request.data.get("email"))

        return Response(status=status.HTTP_200_OK)


#邮箱认证
class EmailActiveView(APIView):
    def get(self,request):
        #获取查询参数token
        token=request.query_params.get("token")
        #判空
        if not token:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        #解密token
        token=User.decode_token(token)

        #获取token的用户id
        user_id=token.get("user_id")

        #获取用户对象
        try:
            user =  User.objects.get(id=user_id)
        except:
            return  Response(status=status.HTTP_400_BAD_REQUEST)

        #修改数据库邮箱状态
        user.email_active=True
        user.save()

        return Response(status=status.HTTP_200_OK)

#收货地址视图
class AddressView(GenericViewSet,
                  mixins.CreateModelMixin,
                  mixins.UpdateModelMixin,
                  mixins.DestroyModelMixin):
    #指定序列化器
    serializer_class = AddressSerializer
    #需要登陆
    permission_classes = [IsAuthenticated]


    #重写
    def get_queryset(self):
        return self.request.user.addresses.filter(is_deleted=False).all()


    #获取所有地址
    def list(self,request):
        #获取当前登陆对象的所有地址的对象集
        query=self.get_queryset()

        #序列化
        serializer=self.get_serializer(instance=query,many=True)

        #组织返回数据
        re_data={
            "addresses":serializer.data,
            "limit":20,
            "default_address_id":self.request.user.default_address_id
        }

        #返回数据
        return Response(data=re_data,status=status.HTTP_200_OK)

    #新建地址
    def create(self, request, *args, **kwargs):
        #查询用户的所有地址
        count=request.user.addresses.filter(is_deleted=False).count()
        #如果地址数量大于20，则删除
        if count>20:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        #增加user_id键值对
        request.data['user_id']=request.user.id

        return super().create(request, *args, **kwargs)

    #修改地址标题
    @action(methods=['put'],detail=True)
    def title(self,request,pk):
        #获取地址对象
        instance = self.get_object()
        #修改数据
        instance.title=request.data.get("title")
        #数据入库
        instance.save()
        #返回响应
        return Response(status=status.HTTP_200_OK)

    #设置默认地址
    @action(methods=['put'], detail=True)
    def status(self,request,pk):
        #设置为默认地址
        request.user.default_address_id=True
        #数据入库
        request.user.save()
        return  Response(status=status.HTTP_200_OK)

    #逻辑删除地址
    def destroy(self, request, *args, **kwargs):

        #获取地址对象
        instance=self.get_object()
        #逻辑删除
        instance.is_deleted=True
        #保存
        instance.save()
        #保存
        return Response(status=status.HTTP_204_NO_CONTENT)


#用户浏览记录
class UserBrowerHistoryView(CreateAPIView):
    #指定序列化器
    serializer_class = UserBrowerHistorySerializer

    def get(self,request):
        #获取redis对象
        redis_conn=get_redis_connection("history")

        #获取用户对象
        user = request.user

        #获取浏览数据的id列表
        sku_ids=redis_conn.lrange("history_%s" %user.id,0,-1)

        #返回数据的列表
        sku_list=[]

        #遍历，组织返回数据
        for sku_id in sku_ids:
            #获取sku对象
            sku = SKU.objects.get(id=sku_id)

            #拼接数据
            dict_data={
                "id":sku.id,
                "name":sku.name,
                "price":sku.price,
                "comments":sku.comments,
                "default_image_url":sku.default_image_url,
            }
            sku_list.append(dict_data)

        return Response(data=sku_list,status=status.HTTP_200_OK)


#重写登陆视图类
class UserObtainJSONWebToken(ObtainJSONWebToken):

    def post(self, request, *args, **kwargs):
        #调用父类登陆方法
        response=super().post(request, *args, **kwargs)

        #获取序列化器
        serializer=self.get_serializer(data=request.data)

        #校验参数，判断是否认证成功
        if serializer.is_valid(raise_exception=True):

            #获取用户对象
            user = serializer.validated_data.get("user")

            #合并购物车
            response = merge_cookie_redis_cart(request,user,response)

        return  response